/*
 * DeterministicFiniteAutomation.cpp
 *
 *  Created on: 01-09-2013
 *      Author: Krzychu
 */

#include "DeterministicFiniteAutomation.h"

#include "../Structures/Config.h"
#include "../Structures/Automaton.h"

#define ASIZE 255

DeterministicFiniteAutomation::DeterministicFiniteAutomation()
{

}

DeterministicFiniteAutomation::~DeterministicFiniteAutomation()
{

}

std::string DeterministicFiniteAutomation::getName()
{
	return "DFA";
}

void preAut(std::string pattern, Automaton* aut)
{
	int patternLength = pattern.length();

	int state, i;
	for (state = aut->getInitial(), i = 0; i < patternLength; ++i)
	{
		int oldTarget = aut->getTarget(state, pattern[i]);
		int target = aut->newVertex();
		aut->setTarget(state, pattern[i], target);
		aut->copyVertex(target, oldTarget);
		state = target;
	}
	aut->setTerminal(state);
}

searchResult DeterministicFiniteAutomation::execute(std::string text, std::string pattern)
{
	searchResult result;
	result.iterationsTaken = 0;

	int textSize = text.size();
	int patternSize = pattern.size();

	/* Preprocessing */
	Automaton* aut = new Automaton(patternSize + 1, (patternSize + 1) * ASIZE);
	preAut(pattern, aut);

	/* Searching */
	for (int state = aut->getInitial(), j = 0; j < textSize; ++j)
	{
		result.iterationsTaken++;

		state = aut->getTarget(state, text[j]);
		if (aut->isTerminal(state))
		{
			result.positionsFound.push_back(j - patternSize + 1);
			if (Config::getInstance()->getFindOneOccurence())
			{
				return result;
			}
		}
	}

	return result;
}
